﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Terraria;
using Terraria.ModLoader;

namespace HardcoreGame.Common.Systems
{
    public class PhysicsItemSystem : ModSystem
    {
        public override void PostUpdateEverything()
        {

            for (int i = 0; i < Main.maxItems; i++)
            {
                Item item = Main.item[i];
                if (item.active && !item.IsAir)
                {
                    Rectangle itemHitbox = item.Hitbox;
                    int j = 0;
                    while (j < Main.maxProjectiles)
                    {
                        Projectile proj = Main.projectile[j];
                        if (proj.active && proj.friendly && proj.damage > 0 && proj.Hitbox.Intersects(itemHitbox))
                        {
                            Vector2 knockbackDir = item.Center - proj.Center;
                            if (knockbackDir == Vector2.Zero)
                            {
                                knockbackDir = Main.rand.NextVector2Unit(0f, 6.2831855f);
                            }
                            knockbackDir.Normalize();
                            item.velocity += knockbackDir * proj.velocity.Length() * 0.5f;
                            if (item.TryGetGlobalItem(out PhysicsItem global))
                            {
                                global.Rotation += Main.rand.NextFloat(-0.2f, 0.2f);
                                break;
                            }
                            break;
                        }
                        else
                        {
                            j++;
                        }
                    }
                    int k = 0;
                    while (k < Main.maxNPCs)
                    {
                        NPC npc = Main.npc[k];
                        if (npc.active && !npc.dontTakeDamage && !npc.townNPC && npc.lifeMax > 5 && npc.Hitbox.Intersects(itemHitbox))
                        {
                            Vector2 knockbackDir2 = item.Center - npc.Center;
                            if (knockbackDir2 == Vector2.Zero)
                            {
                                knockbackDir2 = Main.rand.NextVector2Unit(0f, 6.2831855f);
                            }
                            knockbackDir2.Normalize();
                            item.velocity += knockbackDir2 * 1.5f;
                            if (item.TryGetGlobalItem(out PhysicsItem global2))
                            {
                                global2.Rotation += Main.rand.NextFloat(-0.2f, 0.2f);
                                break;
                            }
                            break;
                        }
                        else
                        {
                            k++;
                        }
                    }
                    for (int l = 0; l < 600; l++)
                    {
                        Gore gore = Main.gore[l];
                        if (gore.active)
                        {
                            Rectangle goreHitbox;
                            goreHitbox = new((int)gore.position.X, (int)gore.position.Y, (int)gore.Width, (int)gore.Height);
                            if (goreHitbox.Intersects(itemHitbox))
                            {
                                Vector2 knockbackDir3 = item.Center - (gore.position + new Vector2(gore.Width, gore.Height) * 0.5f);
                                if (knockbackDir3 == Vector2.Zero)
                                {
                                    knockbackDir3 = Main.rand.NextVector2Unit(0f, 6.2831855f);
                                }
                                knockbackDir3.Normalize();
                                item.velocity += knockbackDir3 * 0.6f;
                                if (item.TryGetGlobalItem(out PhysicsItem global3))
                                {
                                    global3.Rotation += Main.rand.NextFloat(-0.1f, 0.1f);
                                    break;
                                }
                                break;
                            }
                        }
                    }
                    int m = 0;
                    while (m < 255)
                    {
                        Player player = Main.player[m];
                        if (player.active && item.noGrabDelay > 0 && player.Hitbox.Intersects(itemHitbox))
                        {
                            Vector2 knockbackDir4 = item.Center - player.Center;
                            if (knockbackDir4 == Vector2.Zero)
                            {
                                knockbackDir4 = Main.rand.NextVector2Unit(0f, 6.2831855f);
                            }
                            knockbackDir4.Normalize();
                            item.velocity += knockbackDir4 * 1.2f;
                            if (item.TryGetGlobalItem(out PhysicsItem global4))
                            {
                                global4.Rotation += Main.rand.NextFloat(-0.2f, 0.2f);
                                break;
                            }
                            break;
                        }
                        else
                        {
                            m++;
                        }
                    }
                }

            }
            for (int n = 0; n < Main.maxItems; n++)
            {
                Item itemA = Main.item[n];
                if (itemA.active && !itemA.IsAir)
                {
                    Rectangle rectA;
                    rectA = new((int)itemA.position.X, (int)itemA.position.Y, itemA.width, itemA.height);
                    for (int j2 = n + 1; j2 < Main.maxItems; j2++)
                    {
                        Item itemB = Main.item[j2];
                        if (itemB.active && !itemB.IsAir)
                        {
                            Rectangle rectB;
                            rectB = new((int)itemB.position.X, (int)itemB.position.Y, itemB.width, itemB.height);
                            if (rectA.Intersects(rectB))
                            {
                                Vector2 repulse = itemA.Center - itemB.Center;
                                if (repulse == Vector2.Zero)
                                {
                                    repulse = Main.rand.NextVector2Unit(0f, 6.2831855f);
                                }
                                repulse.Normalize();
                                itemA.velocity += repulse * 0.5f;
                                itemB.velocity -= repulse * 0.5f;
                            }
                        }
                    }
                }
            }
        }
    }
    public class PhysicsItem : GlobalItem
    {
        public float Rotation;
        public override bool InstancePerEntity => true;
        public override void PostUpdate(Item item)
        {
            if (item.active && !item.IsAir)
            {
                item.noGrabDelay = item.timeSinceItemSpawned < 20 ? 20 : 1;
                Rotation += item.velocity.X * 0.05f;
                Tile tile = Framing.GetTileSafely(item.Center.ToTileCoordinates());
                if (tile.LiquidAmount > 32)
                {
                    int liquidType = tile.LiquidType;
                    if (liquidType == 0)
                    {
                        item.velocity.Y -= 0.2f;
                        item.velocity.Y = MathHelper.Clamp(item.velocity.Y, -1.5f, 2f);
                        return;
                    }
                    if (liquidType != 2)
                    {
                        return;
                    }
                    item.velocity.Y *= 0.9f;
                    item.velocity.Y = MathHelper.Clamp(item.velocity.Y, -0.5f, 0.5f);
                }
            }
        }
        public override bool CanPickup(Item item, Player player)
        {          
            return item.timeSinceItemSpawned >= 20 && item.Hitbox.Intersects(player.Hitbox);
        }
        public override bool PreDrawInWorld(Item item, SpriteBatch spriteBatch, Color lightColor, Color alphaColor, ref float rotationRef, ref float scale, int whoAmI)
        {
            if (item.TryGetGlobalItem(out PhysicsItem global))
            {
                rotationRef = global.Rotation;
            }
            return true;
        }

    }
}